package stardust.product.platform.webc.spi.servlet.support;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class MultipartContentRequestSupport
{
  
  private HttpServletRequest request;
  
  private List<FileItem> items;
  
  public MultipartContentRequestSupport(HttpServletRequest request) throws FileUploadException
  {
    this.request = request;
    
    if (this.isMultipartContent())
    {
      FileItemFactory factory = new DiskFileItemFactory();
      ServletFileUpload upload = new ServletFileUpload(factory);
      this.items = (List<FileItem>) upload.parseRequest(request);
    }
  }
  
  public boolean isMultipartContent()
  {
    return ServletFileUpload.isMultipartContent(this.request);
  }
  
  public String getParameter(String name)
  {
    if (this.isMultipartContent())
    {
      List<FileItem> item = this.getMultipartContent(name);
      
      return item.isEmpty() ? null : item.get(0).getString();
    }
    else
    {
      return this.request.getParameter(name);
    }
  }
  
  public String[] getParameterValues(String name)
  {
    if (this.isMultipartContent())
    {
      List<FileItem> item = this.getMultipartContent(name);
      String[] values;
      
      if (item.isEmpty())
      {
        return null;
      }
      else
      {
        values = new String[item.size()];
      }
      
      for (int i = 0; i < item.size(); i++)
      {
        values[i] = item.get(i).getString();
      }
      
      return values;
    }
    else
    {
      return request.getParameterValues(name);
    }
  }
  
  public FileItem getMultipartParameter(String name)
  {
    if (this.isMultipartContent())
    {
      List<FileItem> item = this.getMultipartContent(name);
      
      return item.isEmpty() ? null : item.get(0);
    }
    else
    {
      return null;
    }
  }
  
  public FileItem[] getMultipartParameterValues(String name)
  {
    if (this.isMultipartContent())
    {
      List<FileItem> item = this.getMultipartContent(name);
      FileItem[] values;
      
      if (item.isEmpty())
      {
        return null;
      }
      else
      {
        values = new FileItem[item.size()];
      }
      
      for (int i = 0; i < item.size(); i++)
      {
        values[i] = item.get(i);
      }
      
      return values;
    }
    else
    {
      return null;
    }
  }

  public List<FileItem> getMultipartContent(String name)
  {
    List<FileItem> files = new ArrayList<FileItem>();
    boolean isMultipart = ServletFileUpload.isMultipartContent(this.request);
    
    if (!isMultipart)
    {
      return files;
    }

    Iterator<FileItem> itr = items.iterator();

    while (itr.hasNext())
    {
      FileItem item = (FileItem) itr.next();

      if (name != null && name.equalsIgnoreCase(item.getFieldName()))
      {
        files.add(item);
      }
    }
    
    return files;
  }
  
  public Map<String, Object[]> getParameterValuesMap()
  {
    Map<String, Object[]> parameterMap = new HashMap<String, Object[]>();
    
    if (this.isMultipartContent())
    {
      for (int i = 0; i < this.items.size(); i++)
      {
        FileItem fi = this.items.get(i);
        
        if (fi.getName() == null)
        {
          parameterMap.put(fi.getFieldName(), this.getParameterValues(fi.getFieldName()));
        }
        else
        {
          parameterMap.put(fi.getFieldName(), this.getParameterValues(fi.getFieldName()));
        }
      }
    }
    else
    {
      parameterMap.putAll(this.request.getParameterMap());
    }
    
    return parameterMap;
  }
  
  public Map<String, Object> getParameterValueMap()
  {
    Map<String, Object> parameterMap = new HashMap<String, Object>();
    
    if (this.isMultipartContent())
    {
      for (int i = 0; i < this.items.size(); i++)
      {
        FileItem fi = this.items.get(i);
        
        if (fi.getName() == null)
        {
          parameterMap.put(fi.getFieldName(), this.getParameter(fi.getFieldName()));
        }
        else
        {
          parameterMap.put(fi.getFieldName(), fi);
        }
      }
    }
    else
    {
      parameterMap.putAll(this.request.getParameterMap());
      
      Iterator<String> i = parameterMap.keySet().iterator();
      String key;
      String[] values;
      
      while (i.hasNext())
      {
        key = i.next();
        values = (String[]) parameterMap.get(key);
        
        if (values == null || values.length == 0)
        {
          parameterMap.put(key, "");
        }
        else
        {
          parameterMap.put(key, values[0]);
        }
      }
    }
    
    return parameterMap;
  }
  
  public String toString()
  {
    StringBuffer buffer = new StringBuffer();
    
    if (this.isMultipartContent())
    {
      for (int i = 0; i < this.items.size(); i++)
      {
        FileItem fi = this.items.get(i);
        
        buffer.append(fi.getFieldName()).append("=").append(fi.getName() == null ? fi.getString() : "[" + fi.getName() + ", " + fi.getSize() + ", " + fi.getContentType() + "]");
        buffer.append(";");
      }
    }
    else
    {
      Map<?, ?> parameter = this.request.getParameterMap();
      Iterator<?> keys = parameter.keySet().iterator();
      Object key;
      String[] values;
      
      while (keys.hasNext())
      {
        key = keys.next();
        values = this.request.getParameterValues(((String[]) parameter.get(key))[0]);
        
        buffer.append(key).append("=");
        
        if (values == null || values.length == 1)
        {
          buffer.append(values == null ? values : values[0]);
        }
        else
        {
          buffer.append("{");
          
          for (int i = 0; i < values.length; i++)
          {
            buffer.append(values[i]);
            
            if (i < values.length - 1)
            {
              buffer.append(", ");
            }
          }
          
          buffer.append("}");
        }
        
        buffer.append(";");
      }
    }
    
    return buffer.toString();
  }

}
